package cn.yunyichina.provider.clinic.listener;

import cn.yunyichina.provider.clinic.constant.CacheConstant;
import cn.yunyichina.provider.clinic.dao.FuyinApplyDao;
import cn.yunyichina.provider.clinic.service.impl.PayServiceImpl;
import cn.yunyichina.provider.clinic.utils.DateUtils;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.CacheService;
import cn.yunyichina.provider.iface.entity.base.OrderExceptionVo;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.XmlUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.listener.MessageListener;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class YybAliPayMessageListener implements MessageListener<Integer, String> {

    private Logger logger = LoggerFactory.getLogger(YybAliPayMessageListener.class);
    @Autowired
    private  PayServiceImpl payService;

    public void onMessage(ConsumerRecord<Integer, String> integerStringConsumerRecord) {
        String jsonString = integerStringConsumerRecord.value();
        logger.info("YybAliPayMessageListener.onMessage.jsonString -> {}", jsonString);
        try {
            JSONObject jsonObject = JSON.parseObject(jsonString);
            String orderNo = (String) jsonObject.get("out_trade_no");
            String openId = (String) jsonObject.get("buyer_id");
            String appId = (String) jsonObject.get("app_id");
            String tradeNo = (String) jsonObject.get("trade_no");
            String payMode = (String) jsonObject.get("pay_mode");
//            Float payAmount = Float.parseFloat((String) jsonObject.get("total_amount")) * 100;
            BigDecimal payAmount = jsonObject.getBigDecimal("total_amount").multiply(new BigDecimal(100));


            Map<String, String> map = new HashMap<String, String>();
            map.put("order_no", orderNo);
            Response ordResponse = BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get",
                    JsonUtils.toJsonString(map));
            logger.info("YybAliPayMessageListener, ordResponse=" + JSONObject.toJSONString(ordResponse));
            if (!"0".equals(ordResponse.getResultCode())) {
                logger.info("YybAliPayMessageListener, 查询订单失败。");
            }
            OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);

            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("yyt_order_no", orderNo);
            dataMap.put("pay_time", DateUtils.dateToString(new Date()));
            dataMap.put("user_id", openId);
            dataMap.put("payee_app_id", appId);

            Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), HashMap.class);
            if(StringUtils.isNotBlank(extraParamsMap.get("is_from_inner"))) {
                dataMap.put("is_from_inner", "2");
            } else {
                dataMap.put("is_from_inner", "1");
            }
            
            // 根据回调payMode判断是否医保支付
            boolean isCallbackInsurance = false;
            if ("21".equals(payMode) || "22".equals(payMode) || "23".equals(payMode) || "24".equals(payMode)
                    || "25".equals(payMode) || "26".equals(payMode)) {
                // 自费支付
                isCallbackInsurance = false;
            } else if ("27".equals(payMode) || "28".equals(payMode) || "29".equals(payMode)) {
                // 医保支付
                isCallbackInsurance = true;
            } else {
                logger.info("门诊支付回调, 订单号" + order.getOrderNo() + ", paymode不是22和27, 请联系管理员。");
                return;
            }
            
            order.setPayMode(Short.parseShort(payMode));
            dataMap.put("pay_mode", payMode);
            if (order.getIsInsurance().intValue() == 0) {
                dataMap.put("pay_amount", payAmount.intValue());
            } else if (order.getIsInsurance().intValue() == 1) {
                if (isCallbackInsurance) {
                    order.setInsuranceMode((short) 1);

                    String fund_bill_list = (String) jsonObject.get("fund_bill_list");
                    JSONArray jsonArray = JSONObject.parseArray(fund_bill_list);
                    String outsideCardFee = "";
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject jo = jsonArray.getJSONObject(i);
                        if ("OUTSIDECARD".equals(jo.getString("fundChannel"))) {
                            outsideCardFee = jo.getString("amount");
                            logger.info("YybAliPayMessageListener, outsideCardFee=" + outsideCardFee);
                        }
                    }

                    if (StringUtils.isNotBlank(outsideCardFee)) {
                        BigDecimal outsideCardFee_b = new BigDecimal(outsideCardFee);

                        logger.info("YybAliPayMessageListener, before payAmount=" + order.getPayAmount());
                        order.setPayAmount(
                                payAmount.subtract(outsideCardFee_b.multiply(new BigDecimal(100))).intValue());
                        order.setPayRealAmount(order.getPayAmount());
                        dataMap.put("pay_amount", order.getPayAmount());
                        logger.info("YybAliPayMessageListener, after payAmount=" + order.getPayAmount());
                        logger.info("YybAliPayMessageListener, before AccountAmount=" + order.getAccountAmount());
                        // order.setAccountAmount(outsideCardFee_b.multiply(new
                        // BigDecimal(100)).intValue());
                        logger.info("YybAliPayMessageListener, after AccountAmount=" + order.getAccountAmount());
                        logger.info("YybAliPayMessageListener, before InsuranceAmount=" + order.getInsuranceAmount());
                        // modify:zkw
                        order.setInsuranceRealAmount(outsideCardFee_b.multiply(new BigDecimal(100)).intValue());
                        logger.info("YybAliPayMessageListener, after InsuranceAmount=" + order.getInsuranceAmount());
                    }
 
                    String industry_sepc_detail = (String) jsonObject.get("industry_sepc_detail");

                    String tempStr = null;
                    try {
                        // 因为支付宝传入进来的参数中含有"{、}"、"[、]"等这些字符，所以要进行替换才能进行JSON解析
                        tempStr = industry_sepc_detail.replace("\"{", "{");
                        tempStr = tempStr.replace("}\"", "}");
                        tempStr = tempStr.replace("\"[", "[");
                        tempStr = tempStr.replace("]\"", "]");
                    } catch (Exception e) {
                        addOrderToExceptionList(order, "解析settlement或payment出现了异常！");
                        logger.error("解析settlement或payment出现了异常！", e);
                    }

                    extraParamsMap.put("industry_sepc_detail", tempStr);
                } else {
                    dataMap.put("pay_amount", payAmount.intValue());
                }
            } else { 
                logger.info("门诊支付回调, 订单号" + order.getOrderNo() + ", paymode不是22和27, 请联系管理员。");
            }
            order.setExtraParams(JSON.toJSONString(extraParamsMap));
            order.setPaymentDealId(tradeNo);
            order.setIsPayHandled(1);//支付是否通知并处理0：否，1：是

            logger.info("YybAliPayMessageListener, order=" + JSONObject.toJSONString(order));
            BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));
            
            if(payService == null){
                payService = SpringContextHandler.getBean(PayServiceImpl.class);
            }
            Response response = payService.ackPayOrderByOrderNoOut( JsonUtils.toJsonString(dataMap),"");
            logger.info("onMessage 门诊写单 response:{}", JSON.toJSONString(response));

        } catch (Exception e) {
            logger.error("onMessage error.", e);
        }

        logger.info("onMessage end.");
    }


    private void addOrderToExceptionList(OrderExtVo vo, String errMsg) {
        boolean isAdd = true;
        try {
            logger.info("addOrderToExceptionList, yyt.base.order.exception.by.order.no.get request=" + JSON.toJSONString(vo));
            Response response = BaseService.callUnderlineFromInternal("yyt.base.order.exception.by.order.no.get",
                    JsonUtils.toJsonString(vo));
            logger.info("addOrderToExceptionList, yyt.base.order.exception.by.order.no.get response=" + JSON.toJSONString(response));
            if (!"0".equals(response.getResultCode())) {
                logger.info("doExecute, 查询订单失败");
            }

            OrderExceptionVo oe = JsonUtils.parseObject(response.getResult(), OrderExceptionVo.class);
            if (oe != null) {
                isAdd = false;
            }
        } catch (Exception e) {
            logger.info("查询异常单是否存在报错。");
        }

        if (isAdd) {
            logger.info("addOrderToExceptionList, vo=" + JSON.toJSONString(vo));
            OrderExceptionVo record = new OrderExceptionVo();
            record.setBranchCode(vo.getBranchCode());
            record.setBranchId(vo.getBranchId());
            record.setBranchName(vo.getBranchName());
            record.setCreatedTime(DateUtils.dateToString(new Date()));
            record.setExceptionHandlerCount(0);
            record.setRefundHandlerCount(0);
            record.setId(PKGenerator.generateId());
            record.setIsInsurance(vo.getIsInsurance());
            record.setOrderNo(vo.getOrderNo());
            record.setOrderType(vo.getOrderType());
            record.setOrgCode(vo.getOrgCode());
            record.setOrgId(vo.getOrgId());
            record.setOrgName(vo.getOrgName());
            record.setPlatformCode(vo.getPlatformCode());
            record.setPlatformId(vo.getPlatformId());
            record.setPlatformName(vo.getPlatformName());
            record.setPlatformOrgAppCode(vo.getPlatformOrgAppCode());
            record.setUpdateTime(DateUtils.dateToString(new Date()));
            record.setHandlerResult((short) 0);
            record.setHisQueryState((short) 0);
            record.setInsuranceHandlerFlag((short) 0);
            record.setSelfPayHandlerFlag((short) 0);
            //记录写单的异常信息
            record.setExceptionReason(errMsg);
            record.setExceptionClass("Clinic-YybAliPayMessageListener");

            logger.info("addOrderToExceptionList, OrderExceptionVo record=" + JSON.toJSONString(record));
            CacheService.setGlobalKey(CacheConstant.CACHE_CLINIC_MODULE, CacheConstant.CACHE_CLINIC_PAY_EXCEPTION_ORDER,
                    record.getOrderNo(), JSON.toJSONString(record), CacheConstant.CACHE_NOT_EXPIRETIME);

            BaseService.callUnderlineFromInternal("", "yyt.base.order.exception.add", JsonUtils.toJsonString(record));
        }
        logger.info("addOrderToExceptionList end");
    }
}
